"""Test_04"""

import re

REF_ARR_DATE = r'''
    (    # 平年
        (\d{4})
        (((0[13578]|1[02])((0[1-9])|([12][0-9])|(3[01])))|    # 匹配大月31天
        (((0[469])|11)((0[1-9])|([12][1-9])|30))|    # 匹配小月30天
        (02((0[1-9])|(1[0-9])|(2[1-8]))))    # 匹配2月28天
    )
    |
    (    # # 闰年 (四年一闰，百年不闰，四百年再闰)
        (((([02468][048])|([13579][26]))00)|([0-9]{2}(([02468][048])|([13579][26]))))
        (((0[13578]|1[02])((0[1-9])|([12][0-9])|(3[01])))|    # 匹配大月31天
        (((0[469])|11)((0[1-9])|([12][1-9])|30))|    # 匹配小月30天
        (02((0[1-9])|(1[0-9])|(2[1-9]))))    # 匹配2月29天
    )
''' # 松散正则表达式

REG_ARR_DATE_SCOPE = r'''
    (    # 平年
        (19[8-9]\d|2000)   # 匹配范围 1980~2000
        (((0[13578]|1[02])((0[1-9])|([12][0-9])|(3[01])))|    # 匹配大月31天
        (((0[469])|11)((0[1-9])|([12][1-9])|30))|    # 匹配小月30天
        (02((0[1-9])|(1[0-9])|(2[1-8]))))    # 匹配2月28天
    )
    |
    (    # # 闰年 (四年一闰，百年不闰，四百年再闰)
        ((2000)|(19(([8][048])|([9][26]))))
        (((0[13578]|1[02])((0[1-9])|([12][0-9])|(3[01])))|    # 匹配大月31天
        (((0[469])|11)((0[1-9])|([12][1-9])|30))|    # 匹配小月30天
        (02((0[1-9])|(1[0-9])|(2[1-9]))))    # 匹配2月29天
    )
''' # 松散正则表达式
REG_ARR_YEAR = r'''
    (19[6-9]\d|20[0-1]\d|202[0-1])  # 匹配范围 1960~2021
''' # 松散正则表达式
MY_BIRTH = '19930716'

def search_str(_str, reg_str):
    """正则匹配内容

    Args:
        _str (str): 需要匹配的字符串
        reg_str (reg): 正则表达式

    Returns:
        [list]: 输出列表类型，[(索引, 值), ...]
    """
    reg = re.compile(reg_str, re.VERBOSE) # re.VERBOSE 松散正则表达式
    matches = reg.finditer(_str)
    return [(match.start(), match.group()) for match in matches]

def search_near_birth(match_date,arr):
    """查找离自己生日最近的值

    Args:
        match_date (str|int): 你的生日日期 YYYYMMDD
        arr (list): 数据源

    Returns:
        tuple: 返回一个离自己生日最近的元组
    """
    near = (None, None)
    for item in arr:
        if near[1] is None or \
        abs(int(item[1]) - int(match_date)) < abs(int(near[1]) - int(match_date)):
            near = item
            if int(near[1]) == int(match_date):
                break
    return near


with open('./04. regex_exception/pi.txt', 'r', encoding='utf-8') as f:
    try: # 捕获错误，避免影响正常代码的运行
        data = f.read() # 读文件
        arr_date_scope = search_str(data, reg_str=REG_ARR_DATE_SCOPE) # 年份限制范围是 1980-2000
        arr_date = search_str(data, reg_str=REF_ARR_DATE) # 获取出生年月
        arr_near_birth = search_near_birth(MY_BIRTH, arr_date) # 获取离你生日最近的一天
        arr_year = search_str(data, reg_str=REG_ARR_YEAR) # 获取范围内所有匹配到的年份
    except (re.error, ValueError) as e:
        print(e)
    print(
        '查到符合范围的 YYYYMMDD 日期规则=', arr_date_scope,
        '共匹配=', len(arr_date_scope)
    )
    print('查找离你的出生年月最近的一天=', arr_near_birth)
    print(
        '输出范围年份=', arr_year,
        '共匹配=', len(arr_year)
    )
